<template>
  <!--! 这里最好不要使用n-flex,滚动高度会有问题  -->
  <main
    v-if="isGroup"
    :class="
      isCollapsed
        ? 'w-220px border-l-(1px solid [--right-chat-footer-line-color]) p-[12px_0_12px_6px] custom-shadow'
        : 'w-0 pr-1px'
    "
    class="item-box">
    <!-- 收缩按钮 -->
    <div
      @click.stop="isCollapsed = !isCollapsed"
      style="border-radius: 18px 0 0 18px"
      class="contraction transition-all duration-600 ease-in-out absolute top-35% left--14px cursor-pointer opacity-0 bg-#c8c8c833 h-60px w-14px">
      <svg :class="isCollapsed ? 'rotate-180' : 'rotate-0'" class="size-16px color-#909090 absolute top-38%">
        <use href="#left-arrow"></use>
      </svg>
    </div>

    <!-- 群公告 -->
    <n-flex vertical :size="14" class="px-4px py-10px">
      <n-flex align="center" justify="space-between" class="cursor-pointer">
        <p class="text-(14px --text-color) font-bold">简介</p>
      </n-flex>

      <!-- 公告内容 -->
      <n-flex v-if="isLord || isAdmin" class="h-74px">
        <n-input
          v-model:value="groupProfile.introduction"
          @blur="handleSaveIntroduction"
          maxlength="100"
          type="textarea"
          class="bg-[#deeeee]"
          placeholder="简介" />
      </n-flex>
      <n-scrollbar v-else class="h-74px">
        <p class="announcement-text text-(12px #909090) leading-6 line-clamp-4 max-w-99% break-words">
          {{ groupProfile.introduction }}
        </p>
      </n-scrollbar>
    </n-flex>

    <n-flex v-if="!isSearch" align="center" justify="space-between" class="pr-8px pl-8px h-42px">
      <span class="text-14px"> 群成员&nbsp; ({{ groupProfile.memberCount }}) </span>
      <svg @click="handleSelect" class="size-14px">
        <use href="#search" title="搜索"></use>
      </svg>
    </n-flex>
    <!-- 搜索框 -->
    <n-flex v-else align="center" class="pr-8px h-42px">
      <n-input
        :on-input="handleSearch"
        @blur="handleBlur"
        ref="inputInstRef"
        v-model:value="searchRef"
        clearable
        placeholder="搜索"
        type="text"
        size="tiny"
        autoComplete="off"
        autoCorrect="off"
        class="h-26px w-95% lh-26px rounded-6px">
        <template #prefix>
          <svg class="w-12px h-12px">
            <use href="#search"></use>
          </svg>
        </template>
      </n-input>
    </n-flex>

    <!--  // TODO popover显示的时候去改变窗口的大小、当点击了半个选项的时候也会出现原生滚动条 (nyh -> 2024-03-25 05:04:37)  -->
    <!-- // TODO 如果popover显示就先暂时不让滚动，因为在n-scrollbar和n-virtual-list中使用当我点击最后一个选项时候n-popover位置不够导致出现原生滚动条 (nyh -> 2024-03-24 22:46:38) -->
    <!-- // TODO 如果直接使用n-virtual-list的滚动配上n-popover乎也没有这个bug，但是当点击倒数第二个的时候还是会出现滚动条 (nyh -> 2024-03-25 00:30:53)   -->
    <!-- 骨架屏加载中 -->
    <!--    <div v-if="isLoadingMembers" style="max-height: calc(100vh - 260px); overflow-y: hidden">-->
    <!--      <n-flex v-for="i in 6" :key="i" align="center" justify="space-between" class="item px-8px py-10px">-->
    <!--        <n-flex align="center" :size="8" class="flex-1 truncate">-->
    <!--          <n-skeleton text :repeat="1" :width="26" :height="26" circle />-->
    <!--          <n-flex vertical :size="2" class="flex-1 truncate ml-8px">-->
    <!--            <n-skeleton text class="rounded-4px" :width="80" />-->
    <!--            <n-skeleton text class="rounded-4px" :width="60" />-->
    <!--          </n-flex>-->
    <!--        </n-flex>-->
    <!--      </n-flex>-->
    <!--    </div>-->

    <!-- 成员列表 -->
    <n-virtual-list
      id="image-chat-sidebar"
      style="max-height: calc(100vh - 260px)"
      item-resizable
      @scroll="handleScroll($event)"
      :item-size="46"
      :items="filteredUserList">
      <template #default="{ item }">
        <n-popover
          :ref="(el) => (infoPopoverRefs[item.userID] = el)"
          @update:show="handlePopoverUpdate(item.userID, $event)"
          trigger="click"
          placement="left"
          :show-arrow="false"
          style="padding: 0; background: var(--bg-info)">
          <template #trigger>
            <ContextMenu
              :content="item"
              @select="$event.click(item, 'Sidebar')"
              :menu="optionsList"
              :special-menu="report">
              <n-flex
                @click="selectKey = item.userID"
                :key="item.userID"
                :size="10"
                align="center"
                justify="space-between"
                class="item">
                <n-flex align="center" :size="8" class="flex-1 truncate">
                  <div class="relative inline-flex items-center justify-center">
                    <n-avatar
                      round
                      class="grayscale"
                      :class="{ 'grayscale-0': item.isOnline }"
                      :size="26"
                      :src="item.avatar || '/logo.png'"
                      fallback-src="/logo.png" />
                  </div>
                  <n-flex vertical :size="2" class="flex-1 truncate">
                    <p :title="getCompanyAndDepartment(item)" class="text-12px truncate flex-1">
                      {{ getCompanyAndDepartment(item) }}
                    </p>
                    <n-flex
                      v-if="item.userStateId && getUserState(item.userStateId)"
                      align="center"
                      :size="4"
                      class="flex-1">
                      <img class="size-12px" :src="getUserState(item.userStateId)?.url" alt="" />
                      <span class="text-10px text-[--chat-text-color] truncate">
                        {{ getUserState(item.userStateId)?.title }}
                      </span>
                    </n-flex>
                  </n-flex>
                </n-flex>

                <div
                  v-if="item.role === TencentCloudChat.TYPES.GRP_MBR_ROLE_OWNER"
                  class="flex px-4px bg-#d5304f30 py-3px rounded-4px size-fit select-none">
                  <p class="text-(10px #d5304f)">群主</p>
                </div>
                <div
                  v-if="item.role === TencentCloudChat.TYPES.GRP_MBR_ROLE_ADMIN"
                  class="flex px-4px bg-#1a7d6b30 py-3px rounded-4px size-fit select-none">
                  <p class="text-(10px #1a7d6b)">管理员</p>
                </div>
              </n-flex>
            </ContextMenu>
          </template>
          <!-- 用户个人信息框 -->
          <InfoPopover v-if="selectKey === item.userID" :uid="item.userID" :activeStatus="item.isOnline" />
        </n-popover>
      </template>
    </n-virtual-list>
  </main>
</template>
<script setup lang="ts">
import { MittEnum } from '@/enums'
import { InputInst } from 'naive-ui'
import { usePopover } from '@/hooks/usePopover.ts'
import { useChatMain } from '@/hooks/useChatMain.ts'
import { useMitt } from '@/hooks/useMitt.ts'
import { useDebounceFn } from '@vueuse/core'
import { useUserStatusStore } from '@/stores/userStatus'
import { storeToRefs } from 'pinia'
import { useTencentGroupStore } from '@/stores/tencentGroupStore.ts'
import { useTencentConversationStore } from '@/stores/tencentConversationStore.ts'
import TencentCloudChat, { GroupMember } from '@tencentcloud/chat'
import { useTencentUserStore } from '@/stores/tencentUserStore.ts'
import { useMiaoxinCompanyStore } from '@/stores/miaoxinCompanyStore.ts'

const tencentGroupStore = useTencentGroupStore()
const tencentConversationStore = useTencentConversationStore()
const tencentUserStore = useTencentUserStore()
const miaoxinCompanyStore = useMiaoxinCompanyStore()

// 成员列表加载状态
const isLoadingMembers = ref(true)
const isGroup = computed(() => tencentConversationStore.isGROUP)

const groupProfile = computed(() => tencentGroupStore.currentGroup)
const groupMemberMap = computed(() => {
  if (isGroup.value) {
    const members = tencentGroupStore.groupMemberMap[groupProfile.value?.groupID!]
    return Object.values(members)
  }

  return []
})

const userList = computed(() => {
  return groupMemberMap.value
  // return groupMemberMap.value.sort((a, b) => {
  //   // roleId === 1 的排在最前面
  //   // 首先按照roleId排序
  //   if (a.role !== b.role) {
  //     // roleId === 2 的排在第二位
  //     if (a.role === TencentCloudChat.TYPES.GRP_MBR_ROLE_OWNER) return -1
  //     if (b.role === TencentCloudChat.TYPES.GRP_MBR_ROLE_OWNER) return 1
  //     if (a.role === TencentCloudChat.TYPES.GRP_MBR_ROLE_ADMIN) return -1
  //     if (b.role === TencentCloudChat.TYPES.GRP_MBR_ROLE_ADMIN) return 1
  //   }
  //
  //   // if (a?.isOnline) {
  //   //   return b.isOnline - a.isOnline
  //   // }
  //
  //   return a.nick.localeCompare(b.nick)
  // })
})
const filteredUserList = shallowRef(userList.value)
/** 是否是搜索模式 */
const isSearch = ref(false)
const searchRef = ref('')
/** List中的Popover组件实例 */
const infoPopoverRefs = ref<Record<string, any>>([])
const inputInstRef = ref<InputInst | null>(null)
const isCollapsed = ref(true)
const { optionsList, report, selectKey } = useChatMain()
const { handlePopoverUpdate, enableScroll } = usePopover(selectKey, 'image-chat-sidebar')
provide('popoverControls', { enableScroll })

const isLord = computed(() => {
  return tencentUserStore.myProfile.userID === tencentConversationStore.currentConv.groupProfile?.ownerID
})
const isAdmin = computed(() => {
  return tencentConversationStore.currentConv.groupProfile?.selfInfo.role === TencentCloudChat.TYPES.GRP_MBR_ROLE_ADMIN
})

const getCompanyAndDepartment = (item: GroupMember) => {
  const profile = miaoxinCompanyStore.getOrganizationUserProfileById(item.userID)
  return `${item.nameCard || item.nick} (${profile.CompanyNickName}-${profile.DepartmentName})`
}

// 添加一个新的计算属性来合并用户列表
const mergedUserList = computed(() => {
  // 创建一个Map用于去重，使用uid作为key
  const userMap = new Map()

  // 首先添加在线用户列表
  userList.value.forEach((user) => {
    userMap.set(user.userID, user)
  })

  // 转换回数组并按在线状态排序
  return Array.from(userMap.values()).sort((a, b) => a.userID.localeCompare(b.userID))
})

// 修改watch监听器
watch(
  () => userList,
  (newVal) => {
    // 如果正在搜索，则应用搜索过滤
    if (searchRef.value) {
      filteredUserList.value = mergedUserList.value.filter((user) => {
        user.nameCard.toLowerCase().includes(searchRef.value.toLowerCase()) ||
          user.nick.toLowerCase().includes(searchRef.value.toLowerCase())
      })
    } else {
      filteredUserList.value = userList.value
    }

    console.log('监听群聊用户列表', userList, newVal, filteredUserList.value)

    // 判断成员列表是否已加载完成
    if (userList.value.length > 0) {
      isLoadingMembers.value = false
    }
  },
  {
    immediate: true,
    deep: true
  }
)

const handleSaveIntroduction = () => {
  tencentGroupStore.updateGroupProfile({
    groupID: groupProfile.value.groupID,
    introduction: groupProfile.value.introduction
  })
}

/**
 * 监听搜索输入过滤用户
 * @param value 输入值
 */
const handleSearch = useDebounceFn((value: string) => {
  if (!value) {
    // 如果搜索框为空，只显示在线用户列表
    filteredUserList.value = userList.value
    return
  }

  // 从合并后的用户列表中搜索
  filteredUserList.value = mergedUserList.value.filter(
    (user) =>
      user.nameCard.toLowerCase().includes(value.toLowerCase()) || user.nick.toLowerCase().includes(value.toLowerCase())
  )
}, 10)

/**
 * 重置搜索状态
 */
const handleBlur = () => {
  if (searchRef.value) return
  isSearch.value = false
  searchRef.value = ''
  // 重置为只显示在线用户列表
  filteredUserList.value = userList.value
}

/**
 * 处理滚动事件
 * @param event 滚动事件
 */
const handleScroll = (event: Event) => {
  const target = event.target as HTMLElement
  const isBottom = target.scrollHeight - target.scrollTop === target.clientHeight

  if (isBottom && tencentGroupStore.currentGroup?.groupID) {
    tencentGroupStore.getGroupMemberList(tencentGroupStore.currentGroup?.groupID)
  }
}

/**
 * 切换搜索模式并自动聚焦输入框
 */
const handleSelect = () => {
  isSearch.value = !isSearch.value
  nextTick(() => {
    inputInstRef.value?.select()
  })
}

const userStatusStore = useUserStatusStore()
const { stateList } = storeToRefs(userStatusStore)

const getUserState = (stateId: string) => {
  return stateList.value.find((state: { id: string }) => state.id === stateId)
}

onMounted(async () => {
  useMitt.on(`${MittEnum.INFO_POPOVER}-Sidebar`, (event: any) => {
    selectKey.value = event.uid
    infoPopoverRefs.value[event.uid].setShow(true)
    handlePopoverUpdate(event.uid)
  })
})
</script>

<style scoped lang="scss">
@use '@/styles/scss/chat-sidebar';
</style>
